package org.Yiran.timetale_re.weather;

import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.level.saveddata.SavedData;
import net.minecraft.world.level.storage.DimensionDataStorage;
import net.minecraft.server.level.ServerLevel;
import org.jetbrains.annotations.NotNull;

/**
 * 暴风天气数据类
 * <p>
 * 用于存储和管理游戏中的天气数据，包括暴风雨和大风等天气事件的状态信息。
 * 继承自SavedData，支持数据的持久化存储。
 * </p>
 *
 * @author Yiran
 * @version 1.0
 */
public class StormWeatherData extends SavedData {
    
    // ================================
    // 常量定义
    // ================================
    
    /**
     * 数据存储名称
     */
    private static final String DATA_NAME = "timetale_storm_weather";
    
    // ================================
    // 数据字段定义
    // ================================
    
    /**
     * 是否正在下雨/暴风雨
     */
    private boolean isStormy = false;
    
    /**
     * 暴风雨开始时间
     */
    private long stormStartTime = 0;
    
    /**
     * 暴风雨持续时间
     */
    private long stormDuration = 0;
    
    /**
     * 是否正在刮大风
     */
    private boolean isWindy = false;
    
    /**
     * 风力强度，范围 0.0 - 10.0
     */
    private float windIntensity = 0.0f;
    
    /**
     * 风力等级，范围 1-9级
     */
    private int windLevel = 0;

    // ================================
    // 构造方法
    // ================================
    
    /**
     * 构造一个新的暴风天气数据对象
     */
    public StormWeatherData() {
        super();
    }

    // ================================
    // 数据序列化方法
    // ================================
    
    /**
     * 从NBT标签加载天气数据
     * <p>
     * 从给定的NBT标签中读取天气数据并创建StormWeatherData实例
     * </p>
     *
     * @param nbt 包含天气数据的NBT标签
     * @return 加载了数据的StormWeatherData实例
     */
    public static StormWeatherData load(CompoundTag nbt) {
        StormWeatherData data = new StormWeatherData();
        data.isStormy = nbt.getBoolean("IsStormy");
        data.stormStartTime = nbt.getLong("StormStartTime");
        data.stormDuration = nbt.getLong("StormDuration");
        data.isWindy = nbt.getBoolean("IsWindy");
        data.windIntensity = nbt.getFloat("WindIntensity");
        data.windLevel = nbt.getInt("WindLevel");
        return data;
    }

    /**
     * 将天气数据保存到NBT标签
     * <p>
     * 将当前天气数据写入给定的NBT标签并返回
     * </p>
     *
     * @param nbt 用于存储数据的NBT标签
     * @return 包含天气数据的NBT标签
     */
    @Override
    public @NotNull CompoundTag save(CompoundTag nbt) {
        nbt.putBoolean("IsStormy", isStormy);
        nbt.putLong("StormStartTime", stormStartTime);
        nbt.putLong("StormDuration", stormDuration);
        nbt.putBoolean("IsWindy", isWindy);
        nbt.putFloat("WindIntensity", windIntensity);
        nbt.putInt("WindLevel", windLevel);
        return nbt;
    }

    // ================================
    // 数据获取方法
    // ================================
    
    /**
     * 获取指定世界的天气数据
     * <p>
     * 从世界的存储中获取StormWeatherData实例，如果不存在则创建新的实例
     * </p>
     *
     * @param level 服务器世界对象
     * @return 该世界的StormWeatherData实例
     */
    public static StormWeatherData get(ServerLevel level) {
        DimensionDataStorage storage = level.getDataStorage();
        return storage.computeIfAbsent(
            StormWeatherData::load,
            StormWeatherData::new,
            DATA_NAME
        );
    }

    // ================================
    // 暴风雨相关方法
    // ================================
    
    /**
     * 检查是否正在下雨/暴风雨
     *
     * @return 如果正在下雨/暴风雨返回true，否则返回false
     */
    public boolean isStormy() {
        return isStormy;
    }

    /**
     * 设置是否正在下雨/暴风雨
     *
     * @param stormy true表示正在下雨/暴风雨，false表示没有暴风雨
     */
    public void setStormy(boolean stormy) {
        this.isStormy = stormy;
        this.setDirty(); // 标记数据已更改
    }

    /**
     * 获取暴风雨开始时间
     *
     * @return 暴风雨开始时间（游戏刻）
     */
    public long getStormStartTime() {
        return stormStartTime;
    }

    /**
     * 设置暴风雨开始时间
     *
     * @param stormStartTime 暴风雨开始时间（游戏刻）
     */
    public void setStormStartTime(long stormStartTime) {
        this.stormStartTime = stormStartTime;
        this.setDirty();
    }

    /**
     * 获取暴风雨持续时间
     *
     * @return 暴风雨持续时间（游戏刻）
     */
    public long getStormDuration() {
        return stormDuration;
    }

    /**
     * 设置暴风雨持续时间
     *
     * @param stormDuration 暴风雨持续时间（游戏刻）
     */
    public void setStormDuration(long stormDuration) {
        this.stormDuration = stormDuration;
        this.setDirty();
    }

    /**
     * 获取暴风雨结束时间
     *
     * @return 暴风雨结束时间（游戏刻）
     */
    public long getStormEndTime() {
        return stormStartTime + stormDuration;
    }

    // ================================
    // 大风相关方法
    // ================================
    
    /**
     * 检查是否正在刮大风
     *
     * @return 如果正在刮大风返回true，否则返回false
     */
    public boolean isWindy() {
        return isWindy;
    }

    /**
     * 设置是否正在刮大风
     *
     * @param windy true表示正在刮大风，false表示没有大风
     */
    public void setWindy(boolean windy) {
        this.isWindy = windy;
        this.setDirty();
    }

    /**
     * 获取风力强度
     *
     * @return 风力强度值，范围 0.0 - 10.0
     */
    public float getWindIntensity() {
        return windIntensity;
    }

    /**
     * 设置风力强度
     *
     * @param windIntensity 风力强度值，范围 0.0 - 10.0
     */
    public void setWindIntensity(float windIntensity) {
        this.windIntensity = windIntensity;
        this.setDirty();
    }

    /**
     * 获取风力等级
     *
     * @return 风力等级，范围 1-9级
     */
    public int getWindLevel() {
        return windLevel;
    }

    /**
     * 设置风力等级
     *
     * @param windLevel 风力等级，范围 1-9级
     */
    public void setWindLevel(int windLevel) {
        this.windLevel = windLevel;
        this.setDirty();
    }

    /**
     * 根据风力等级设置风力强度
     * <p>
     * 将风力等级转换为对应的强度值，等级与强度值相等
     * </p>
     *
     * @param level 风力等级 (1-9)
     */
    public void setWindLevelWithIntensity(int level) {
        if (level < 1) level = 1;
        if (level > 9) level = 9;

        this.windLevel = level;
        // 将等级转换为强度值 (等级1=1.0强度, 等级9=9.0强度)
        this.windIntensity = (float) level;
        this.setDirty();
    }
}